import os from "os";
import path from "path";
import { sleep, getAdbProgram } from "../../utils.js";
import { execResolveJustContent } from "../../promisify-api.js";

const tmpdir = os.tmpdir(); // 系统临时路径
// 执行adb程序的封装
const execAdb = async (script) => {
  const adbProgram = getAdbProgram();
  const myScript = `${adbProgram} ${script}`;
  const res = await execResolveJustContent(myScript);
  return res;
};

// 上传文件的路径
const apkPath = "/storage/emulated/0/Download/";

export const loadDevices = async () => {
  // 加载adb设备
  const stdout = await execAdb("devices");
  console.log(stdout);
  
  const lines = stdout.split("\n").filter((line) => line.trim() !== ""); // 去除空行
  const devices = lines.map((line) => {
    const parts = line.trim().split(/\s+/); // 使用一个或多个空格作为分隔符
    return { id: parts[0], status: parts[1] };
  });
  devices.shift();
  return devices;
};

export const getDeviceProp = async (param) => {
  // 获取adb设备信息
  const stdout = await execAdb(`-s ${param} shell getprop`);
  // 使用换行符分割文本为数组
  const lines = stdout.trim().split("\n");
  // 使用reduce方法将数组转换为对象
  const obj = lines.reduce((accumulator, line) => {
    // 使用冒号和空格分割每一行
    const [keyStr, valueStr] = line
      .split(":")
      .map((str) => str.trim().slice(1, -1)); // 移除方括号
    // 尝试将值转换为数字（如果可能），否则保持为字符串
    const value = isNaN(Number(valueStr)) ? valueStr : Number(valueStr);
    // 将键值对添加到累加器中
    accumulator[keyStr] = value;
    // 返回累加器供下一次迭代使用
    return accumulator;
  }, {}); // 初始累加器为一个空对象

  return obj;
};

export const getMemAndDisk = async (deviceId) => {
  // 获取设备内存和硬盘信息
  const stdoutMem = await execAdb(
    `-s ${deviceId} shell "cat /proc/meminfo | grep MemTotal "`
  );
  const stdoutDf = await execAdb(`-s ${deviceId} shell df /data`);

  const parseDf = (stdout) => {
    // 将df的输出转换为数组
    const lines = stdout.trim().split("\n");
    lines.shift();

    // 假设df的输出是固定列数的，可以进一步解析每一列
    const jsonData = lines.map((line) => {
      const columns = line.trim().split(/\s+/); // 根据实际分隔符调整正则表达式
      // 根据df的列结构创建对象，这里只是一个简单例子
      return {
        filesystem: columns[0],
        size: Math.ceil(columns[1] / 1000 / 1000),
        used: Math.ceil(columns[2] / 1000 / 1000),
        available: columns[3],
        // ... 根据需要添加更多属性
      };
    });
    return jsonData[0];
  };

  return {
    memory: Math.ceil(stdoutMem.match(/\d+/)[0] / 1000 / 1000),
    disk: parseDf(stdoutDf),
  };
};

export const installApk = async (deviceId, files) => {
  const win = global.app.mainWindow;
  // 安装软件
  for (const file of files) {
    win.webContents.send("installApk", { path: file, status: "上传中" });

    const stdout1 = await execAdb(`-s ${deviceId} push ${file} ${apkPath}`);
    win.webContents.send("installApk", { path: file, status: "上传完成" });

    await sleep(500);
    win.webContents.send("installApk", { path: file, status: "安装中" });

    // SELinux限制：新版安卓禁止从/data/local/tmp受信任区域外的位置安装应用
    const newFile = apkPath + file.split(/[\\\/]/).pop(); // 安装指定位置的apk
    try {
      const stdout2 = await execAdb(
        `-s ${deviceId} shell "cat ${newFile} | pm install -S $( ls -l ${newFile} | awk '{ print $5 }'" )`
      );
      win.webContents.send("installApk", { path: file, status: "安装成功" });
    } catch (error) {
      win.webContents.send("installApk", { path: file, status: "安装失败" });
    }
  }
};

export const pushFile = async (deviceId, files) => {
  // 推送文件到设备
  const filesPath = files.join(" ");
  const stdout = await execAdb(`-s ${deviceId} push ${filesPath} ${apkPath}`);
  return stdout;
};

export const screen = async (deviceId) => {
  // 截屏
  const screenPath = path.join(apkPath, "screen.png");
  const stdout1 = await execAdb(
    `-s ${deviceId} shell screencap -p ${screenPath}`
  );
  const stdout2 = await execAdb(`-s ${deviceId} pull ${screenPath} ${tmpdir}`);
  return "file://" + path.join(tmpdir, "screen.png");
};

export const getPkgs = async (deviceId, type = "") => {
  // 获取已经安装的应用列表
  const typeTemp = type ? "-" + type : "";
  const packagesAllPr = execAdb(
    `-s ${deviceId} shell pm list packages ${typeTemp}`
  );
  const packagesDisablePr = execAdb(`-s ${deviceId} shell pm list packages -d`);
  const [packagesAllRes, packagesDisableRes] = await Promise.all([
    packagesAllPr,
    packagesDisablePr,
  ]);
  const packagesAll = packagesAllRes
    .trim()
    .split("\n")
    .map((pkg) => pkg.replace(/^package:/, "").replace(/\r$/, ""));
  const packagesDisable = packagesDisableRes
    .trim()
    .split("\n")
    .map((pkg) => pkg.replace(/^package:/, "").replace(/\r$/, ""));

  // 获取冻结的应用
  const packages = packagesAll.map((pkg) => ({
    name: pkg,
    disable: packagesDisable.includes(pkg),
  }));
  return packages;
};

export const unInstall = async (deviceId, pkgId) => {
  // 卸载
  const stdout = await execAdb(
    `-s ${deviceId} shell  pm uninstall --user 0 ${pkgId}`
  );
  return stdout;
};

export const disableApp = async (deviceId, pkgId, enable = false) => {
  // 解冻或冻结
  if (enable) {
    const stdout = await execAdb(`-s ${deviceId} shell pm enable ${pkgId}`);
    return stdout;
  } else {
    const stdout = await execAdb(
      `-s ${deviceId} shell pm disable-user ${pkgId}`
    );
    return stdout;
  }
};
